#pragma once

#include<BWAPI.h>
#include<math.h>
#include<string>

using namespace BWAPI;

using std::string;

#include"ControlerCommon.h"

class ZerglingControler
{
public:
	ZerglingControler(Unit* zergling)
		:_me(zergling),
		_target(NULL),
		_state(Idle),
		_frameToWait(0)
	{
	}
	void OnFrame()
	{
		PrintInfomation();

		bool enable = true;

		if(enable && _target != NULL)
		{
			if(_target->getHitPoints() <= 0)
			{
				_state = Idle;
			}
			switch(_state)
			{
			case Idle:
				_state = ChaseAttack;
				break;
			case ChaseAttack:
				ChaseAttackFunction();
				break;
			case WaitForCheck:
				WaitForCheckFunction();
				break;
			case WaitAttackFrame:
				WaitAttackFrameFunction();
				break;
			case ChaseDontAttack:
				ChaseDontAttackFunction();
				break;
			}
		}
	}
	void DoAttackChase(Unit* target)
	{
		_target = target;
	}
	bool CanAttack() const
	{
	}
private:
	enum State{Idle , ChaseAttack , WaitForCheck , WaitAttackFrame , ChaseDontAttack};
	void ChaseAttackFunction()
	{
		Position enemyPositionAfter3FramePrediction(PredictFuturePosition(_target , 3));
		Position myPositionAfter3FramePrediction(PredictFuturePosition(_me , 3));
		if(GetEdgeDistance(_me->getType() , myPositionAfter3FramePrediction , _target->getType() , enemyPositionAfter3FramePrediction) <= _me->getType().groundWeapon().maxRange())
		{
			//_me->stop();
			_me->attack(_target);
			Broodwar->printf("Attack");
			_state = WaitForCheck;
			_frameToWait = DELAY;
			a = 0;
		}
		else
		{
			JustChase();
		}
	}
	void WaitForCheckFunction()
	{
		if(_me->getGroundWeaponCooldown() > 0)
		{
			++a;
			if(a >= 2)
			{
			_frameToWait = 3;
			_state = WaitAttackFrame;
			_me->stop();
			}
		}
		else
		{
			--_frameToWait;
			if(_frameToWait <= 0)
			{
				_state = ChaseAttack;
			}
		}
	}
	void WaitAttackFrameFunction()
	{
		--_frameToWait;
		if(_frameToWait <= 0)
		{
			_state = ChaseDontAttack;
			//_me->stop();
		}
	}
	void ChaseDontAttackFunction()
	{
		if(_me->getGroundWeaponCooldown() <= DELAY + 1)
		{
			_state = ChaseAttack;
		}
		else
		{
			JustChase();
		}
	}
	void JustChase()
	{
		//if(Broodwar->getFrameCount() % 5 == 0)
		{
			Position enemyPositionAfter4FramePrediction(PredictFuturePosition(_target , 4));
			//Position closestReachablePosition;
			//_me->move(closestReachablePosition);
			//_me->move(enemyPositionAfter4FramePrediction);
			
			_me->move(_target->getPosition());
			Broodwar->printf("Move");
		}
	}
	void PrintInfomation() const
	{
		Position unitPosition = _me->getPosition();
		Broodwar->drawTextMap(unitPosition.x() , _me->getTop() - 10 , "%s" , _me->isStartingAttack()?"\x03 Start attack":"Not Start attack");
		Broodwar->drawTextMap(unitPosition.x() , _me->getTop() - 18 , "%s" , _me->isAttackFrame()?"\x03 is AttackFrame":"Not AttackFrame");
		Broodwar->drawTextMap(unitPosition.x() , _me->getTop() - 26 , "%s" , _me->isAttacking()?"\x03 is Attacking":"Not Attacking");
		Broodwar->drawTextMap(unitPosition.x() , _me->getTop() - 34 , "Z: %d" , _me->getGroundWeaponCooldown());
		string s;
		if(_state == Idle){s = "Idle";}
		if(_state == ChaseAttack){s = "ChaseAttack";}
		if(_state == WaitForCheck){s = "WaitForCheck";}
		if(_state == WaitAttackFrame){s = "WaitAttackFrame";}
		if(_state == ChaseDontAttack){s = "ChaseDontAttack";}
		Broodwar->drawTextMap(unitPosition.x() , _me->getTop() - 42 , "%s" , s.c_str());
	}
	//--
	int a;
	Unit* _me;
	Unit* _target;
	State _state;
	int _frameToWait;
};